package com.acmedcare.framework.exchange.center;

import com.acmedcare.framework.exchange.center.core.handler.PluginHandlerMBean;
import com.acmedcare.framework.exchange.center.core.handler.Request;
import com.acmedcare.framework.exchange.center.core.metadata.ResponseConvert;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.Enumeration;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/gateway")
@Api(tags = "数据仓库开发平台，统一接口")
public class RepositoryGatewayEndpoint {

  private final PluginHandlerMBean handler;
  private final ObjectMapper objectMapper;

  public RepositoryGatewayEndpoint(
      PluginHandlerMBean handler, ObjectMapper objectMapper) {
    this.handler = handler;
    this.objectMapper = objectMapper;
  }

  @GetMapping("plugins/{pluginName}/adapters/{adapterName}")
  @ApiOperation("查询数据仓库数据")
  public ResponseEntity<?> get(@PathVariable("pluginName") String pluginName,
      @PathVariable("adapterName") String adapterName, HttpServletRequest request)
      throws Exception {

    HashMap<String, String> parameters = new HashMap<>();
    Enumeration<String> enumeration = request.getParameterNames();
    if (enumeration != null) {

      while (enumeration.hasMoreElements()) {

        String key = enumeration.nextElement();
        parameters.put(key, request.getParameter(key));
      }
    }
    return routing(pluginName, adapterName, null, HttpMethod.GET, parameters);
  }

  @PostMapping("plugins/{pluginName}/adapters/{adapterName}")
  @ApiOperation("将数据写入到数据仓库")
  public ResponseEntity<?> post(@PathVariable("pluginName") String pluginName,
      @PathVariable("adapterName") String adapterName,
      @RequestBody Object body) throws Exception {

    return routing(pluginName, adapterName, body, HttpMethod.POST, null);
  }


  @PutMapping("plugins/{pluginName}/adapters/{adapterName}")
  @ApiOperation("将数据跟新到数据仓库")
  public ResponseEntity<?> put(@PathVariable("pluginName") String pluginName,
      @PathVariable("adapterName") String adapterName,
      @RequestBody Object body) throws Exception {

    return routing(pluginName, adapterName, body, HttpMethod.PUT, null);
  }

  @DeleteMapping("plugins/{pluginName}/adapters/{adapterName}")
  @ApiOperation("删除数据仓库数据")
  public ResponseEntity<?> delete(@PathVariable("pluginName") String pluginName,
      @PathVariable("adapterName") String adapterName,
      @RequestBody Object body) throws Exception {

    return routing(pluginName, adapterName, body, HttpMethod.DELETE, null);
  }

  private ResponseEntity routing(String pluginName, String adapterName, Object body
      , HttpMethod method, HashMap<String, String> parameters)
      throws Exception {

    Request request = new Request();
    request.setHttpMethod(method);
    request.setPluginName(pluginName);
    request.setUrl(adapterName);
    request.setParameters(parameters);

    if (body != null) {

      request.setBody(objectMapper.writeValueAsString(body));
    }

    ResponseConvert response = handler.invoke(request);

    if (response.getBody() != null) {

      if (response.getStatus() == 200) {

        return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(response.getBody());
      }

      return ResponseEntity.status(HttpStatus.resolve(response.getStatus()))
          .body(response.getBody());
    }

    return ResponseEntity.status(HttpStatus.resolve(response.getStatus()))
        .build();
  }
}